﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace AutoLoL.Logic.Parsers
{
    public class ImageParser
    {
        public static BitmapSource TgaToBitmapSource(string path)
        {
            byte[] data = File.ReadAllBytes(path);
            return TgaToBitmapSource(data);
        }

        public static BitmapSource TgaToBitmapSource(byte[] data)
        {
            return Parse(data, Tao.DevIl.Il.IL_TGA, true);
        }

        public static BitmapSource DdsToBitmapSource(string path)
        {
            byte[] data = File.ReadAllBytes(path);
            return DdsToBitmapSource(data);
        }

        public static BitmapSource DdsToBitmapSource(byte[] data)
        {
            return Parse(data, Tao.DevIl.Il.IL_DDS);
        }

        // NOTE - TGA images require to be flipped vertically
        private static BitmapSource Parse(byte[] data, int format, bool flipVertical = false)
        {
            int imageId;
            Tao.DevIl.Il.ilInit();

            Tao.DevIl.Il.ilGenImages(1, out imageId);
            Tao.DevIl.Il.ilBindImage(imageId);

            BitmapSource result = null;

            if (Tao.DevIl.Il.ilLoadL(format, data, data.Length))
            {
                // Get the image size
                int imageWidth = Tao.DevIl.Il.ilGetInteger(Tao.DevIl.Il.IL_IMAGE_WIDTH);
                int imageHeight = Tao.DevIl.Il.ilGetInteger(Tao.DevIl.Il.IL_IMAGE_HEIGHT);

                // Create a bitmap
                Bitmap bitmap = new Bitmap(imageWidth, imageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                Rectangle rect = new Rectangle(0, 0, imageWidth, imageHeight);
                BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                Tao.DevIl.Il.ilCopyPixels(0, 0, 0, imageWidth, imageHeight, 1, Tao.DevIl.Il.IL_BGRA, Tao.DevIl.Il.IL_UNSIGNED_BYTE, bitmapData.Scan0);

                bitmap.UnlockBits(bitmapData);

                if (flipVertical)
                {
                    bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                }

                // Convert bitmap to BitmapSource
                result = BitmapToBitmapSource(bitmap);
            }

            Tao.DevIl.Il.ilDeleteImages(1, ref imageId);

            return result;
        }

        public static BitmapSource BitmapToBitmapSource(Bitmap bitmap)
        {
            BitmapSource result;
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, ImageFormat.Bmp);
                stream.Seek(0, SeekOrigin.Begin);
                BitmapDecoder decoder = new BmpBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                result = decoder.Frames[0];
            }

            return result;
        }

        public static BitmapImage FileToBitmapImage(string imagePath, bool deleteOriginal = false)
        {
            if (File.Exists(imagePath))
            {
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.StreamSource = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
                bmp.CacheOption = BitmapCacheOption.OnLoad;
                bmp.EndInit();
                bmp.StreamSource.Dispose();
                bmp.Freeze();

                if (deleteOriginal)
                {
                    try
                    {
                        File.Delete(imagePath);
                    }
                    catch { if (Debugger.IsAttached) throw; }
                }

                return bmp;
            }

            return null;
        }

        public static Bitmap MirrorBitmap(Bitmap bitmap)
        {
            return null;
        }

        public static BitmapSource BitmapImageToGreyScale(BitmapSource bitmapSource)
        {
            FormatConvertedBitmap grayBitmap = new FormatConvertedBitmap();
            grayBitmap.BeginInit();
            grayBitmap.Source = bitmapSource;
            grayBitmap.DestinationFormat = PixelFormats.Gray8;
            grayBitmap.EndInit();

            return grayBitmap;
        }
    }
}
